﻿//使用TransactionScope包裹两个DbContext的操作，确保事务一致性：

namespace 用EFCore时如何实现一个分布式事务
{
    using Microsoft.EntityFrameworkCore;
    using System.Transactions;
     
    public class OrderService
    {
        private readonly OrderDbContext _orderDbContext;
        private readonly InventoryDbContext _inventoryDbContext;

        /// <summary>
        /// 注入两个数据库上下文
        /// </summary>
        /// <param name="orderDbContext"></param>
        /// <param name="inventoryDbContext"></param>
        public OrderService(OrderDbContext orderDbContext, InventoryDbContext inventoryDbContext)
        {
            _orderDbContext = orderDbContext;
            _inventoryDbContext = inventoryDbContext;
        }

        /// <summary>
        /// 跨库创建订单并扣减库存（分布式事务）
        /// </summary>
        public async Task CreateOrderWithInventoryAsync(int productId, int quantity)
        {
            // 1. 配置事务选项（超时时间、隔离级别）
            var transactionOptions = new TransactionOptions
            {
                Timeout = TimeSpan.FromSeconds(30), // 事务超时时间
                IsolationLevel = IsolationLevel.ReadCommitted // 隔离级别（按需设置）
            };

            // 2. 创建TransactionScope，自动管理分布式事务
            // - TransactionScopeAsyncFlowOption.Enabled：支持异步操作
            using (var scope = new TransactionScope(
                TransactionScopeOption.Required,
                transactionOptions,
                TransactionScopeAsyncFlowOption.Enabled))
            {
                try
                {
                    // 3. 操作订单库：创建订单
                    var order = new Order
                    {
                        ProductId = productId,
                        Quantity = quantity,
                        CreateTime = DateTime.Now
                    };
                    _orderDbContext.Orders.Add(order);
                    await _orderDbContext.SaveChangesAsync(); // 自动加入分布式事务

                    // 4. 操作库存库：扣减库存
                    var inventory = await _inventoryDbContext.Inventories
                        .FirstOrDefaultAsync(i => i.ProductId == productId);

                    if (inventory == null || inventory.Stock < quantity)
                    {
                        throw new Exception("库存不足，无法创建订单");
                    }

                    inventory.Stock -= quantity;
                    await _inventoryDbContext.SaveChangesAsync(); // 自动加入分布式事务

                    // 5. 所有操作成功，提交事务
                    scope.Complete();
                }
                catch (Exception)
                {
                    // 6. 发生异常时，不调用Complete()，事务自动回滚
                    throw; // 向上抛出，由调用方处理
                }
            }
        }
    }

}
